use shq_common::prelude::{get_my_pool, User};
use sqlx::Row;
// 登录处理函数
pub async fn user_login(user_no: &str, user_pwd: &str) -> anyhow::Result<User> {
    let sql = "SELECT id,emnm,emno,dpid,dpnm,pdid,pwd,stat FROM v_user_organ WHERE emno = ?";
    let row = sqlx::query(sql)
        .bind(user_no)
        .fetch_optional(get_my_pool())
        .await
        .map_err(|e| anyhow::anyhow!("查询用户信息失败: {}", e))?;
    if row.is_none() {
        return Err(anyhow::anyhow!("用户不存在，登录失败"));
    }
    let row = row.unwrap();
    let dpnm: String = row.try_get("dpnm")?;
    if dpnm.contains("离职") {
        return Err(anyhow::anyhow!("用户所在部门: {}，登录失败", dpnm));
    }
    let stat: String = row.try_get("stat")?;
    if stat != "1" {
        let stat_name = match stat.as_str() {
            "2" => "离职",
            "3" => "禁用",
            _ => "未知状态",
        };
        return Err(anyhow::anyhow!("用户状态: {}，登录失败", stat_name));
    }
    let pwd: String = row.try_get("pwd")?;
    let pwd_hash = hash_password(user_no, user_pwd);
    if pwd != pwd_hash {
        return Err(anyhow::anyhow!("密码错误，登录失败"));
    }
    let id: u32 = row.try_get("id")?;
    let no: String = row.try_get("emno")?;
    let dpid: u32 = row.try_get("dpid")?;
    let pdid: u32 = row.try_get("pdid")?;
    let user = User {
        id,
        no,
        name: row.try_get("emnm")?,
        dpid,
        dpnm,
        pdid,
    };
    Ok(user)
}

pub async fn change_password(user_id: u32, old_pwd: &str, new_pwd: &str) -> anyhow::Result<()> {
    let sql="select no,password from sys_user where id=?";
    let row=sqlx::query(sql).bind(user_id).fetch_one(get_my_pool()).await.map_err(|e|anyhow::anyhow!("用户不存在: {}",e))?;
    let uno:String=row.try_get("no")?;
    let pwd:String=row.try_get("password")?;
    let old_pwd_hash=hash_password(uno.as_str(), old_pwd);
    if pwd!=old_pwd_hash {
        return Err(anyhow::anyhow!("旧密码错误"));
    }
    let pwd=hash_password(uno.as_str(), new_pwd);
    let sql = "UPDATE sys_user SET password = ? WHERE id = ?";
    sqlx::query(sql)
        .bind(pwd)
        .bind(user_id)
        .execute(get_my_pool())
        .await
        .map_err(|e| anyhow::anyhow!("修改密码失败: {}", e))?;
    Ok(())
}

pub async fn init_password(user_id: u32) -> anyhow::Result<()> {
    let sql="select no from sys_user where id=?";
    let row=sqlx::query(sql).bind(user_id).fetch_one(get_my_pool()).await.map_err(|e|anyhow::anyhow!("用户不存在: {}",e))?;
    let uno:String=row.try_get("no")?;
    let pwd=hash_password(uno.as_str(), "00000000");
    let sql = "UPDATE sys_user SET password = ? WHERE id = ?";
    sqlx::query(sql)
        .bind(pwd)
        .bind(user_id)
        .execute(get_my_pool())
        .await
        .map_err(|e| anyhow::anyhow!("初始化密码失败: {}", e))?;
    Ok(())
}

use base64::{self, prelude::BASE64_STANDARD, Engine};
use sha1::{Digest, Sha1};

fn hash_password(user_no: &str, password: &str) -> String {
    // Create a SHA-1 hasher
    let mut hasher = Sha1::new();
    // Convert the string to UTF-16LE
    let user_and_pwd = format!("{}{}", user_no, password);
    let utf16_bytes = utf8_to_utf16le(&user_and_pwd);
    // Update the hasher with the bytes
    hasher.update(utf16_bytes);
    // Get the hash result and encode as base64
    let result = hasher.finalize();
    BASE64_STANDARD.encode(&result)
}

fn utf8_to_utf16le(input: &str) -> Vec<u8> {
    // 先把UTF-8字符串转为UTF-16编码的字节序列
    let utf16_words: Vec<u16> = input.encode_utf16().collect();
    // 接着把每个u16类型的值拆分成两个u8类型的值，按照小端序排列
    let mut result = Vec::with_capacity(utf16_words.len() * 2);
    for word in utf16_words {
        result.push(word as u8); // 低字节
        result.push((word >> 8) as u8); // 高字节
    }
    result
}
